﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using Microsoft.Reporting.WebForms;
using TamoCRM.Core;
using TamoCRM.Core.Commons.Extensions;
using TamoCRM.Domain.ContactLevelInfos;
using TamoCRM.Domain.Contacts;
using TamoCRM.Domain.Reports;
using TamoCRM.Services.CallHistories;
using TamoCRM.Services.Channels;
using TamoCRM.Services.Collectors;
using TamoCRM.Services.ContactLevelInfos;
using TamoCRM.Services.Contacts;
using TamoCRM.Services.ImportExcels;
using TamoCRM.Services.Latch;
using TamoCRM.Services.Locations;
using TamoCRM.Services.Lumped;
using TamoCRM.Services.Majors;
using TamoCRM.Services.Phones;
using TamoCRM.Services.Report;
using TamoCRM.Services.Schools;
using TamoCRM.Services.SourceTypes;
using TamoCRM.Services.StatusMap;
using TamoCRM.Services.UserRole;
using TamoCRM.Web.Framework;
using TamoCRM.Web.Framework.Controllers;
using TamoCRM.Web.Framework.Users;
using TamoCRM.Web.Mvc.Areas.Admin.Models.Reports;

namespace TamoCRM.Web.Mvc.Areas.Admin.Controllers
{

    public class ReportController : AdminController
    {
        /// <summary>
        /// Báo cáo lọc trùng L0 L1
        /// </summary>
        public ActionResult BC01()
        {
            var model = new BC01Model { AllCollectors = CollectorRepository.GetAll() };
            return View(model);
        }
        public ActionResult ShowBC01(int collectorId, string from, string to)
        {
            var dtFrom = DateTime.ParseExact(from, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            var dtTo = DateTime.ParseExact(to, "dd/MM/yyyy", CultureInfo.InvariantCulture).AddDays(1).AddSeconds(-1);
            var collector = StoreData.ListCollector.FirstOrDefault(c => c.CollectorId == collectorId) ??
                            CollectorRepository.GetInfo(collectorId);
            var infomation = string.Empty;
            if (collector != null) infomation += "Người lấy: " + collector.Name + " - ";
            infomation += "Từ ngày: " + dtFrom.ToString("dd/MM/yyyy") + " - Đến ngày: " + dtTo.ToString("dd/MM/yyyy");

            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC01.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", infomation));
            var lstImports = ImportExcelRepository.GetForBC01(collectorId, dtFrom, dtTo);
            var lstData = new List<BC01DataModel>();
            foreach (var info in lstImports)
            {
                var objModel = new BC01DataModel();
                var typeInfo = SourceTypeRepository.GetInfo(info.TypeId);
                objModel.SourceType = typeInfo != null ? typeInfo.Code : "Không xác định";
                objModel.Filename = info.FilePath.Substring(info.FilePath.LastIndexOf("\\") + 1);
                objModel.Duplicate = info.DuplicateCount;
                objModel.L0A = info.TotalRow;
                objModel.L0B = info.TotalRow - info.InternalDuplicateCount;
                objModel.L1 = info.TotalRow - info.ErrorCount - info.DuplicateCount - info.InternalDuplicateCount;
                objModel.L1Percentage = objModel.L0A > 0 ? (objModel.L1 * 100 / objModel.L0A) + "%" : "0%";
                lstData.Add(objModel);
            }
            var reportDataSource = new ReportDataSource("BC01", lstData);
            localReport.DataSources.Add(reportDataSource);
            const string reportType = "pdf";
            string mimeType;
            string encoding;
            string fileNameExtension;
            //The DeviceInfo settings should be changed based on the reportType             
            //http://msdn2.microsoft.com/en-us/library/ms155397.aspx             
            const string deviceInfo = "<DeviceInfo>" +
                                      "  <OutputFormat>PDF</OutputFormat>" +
                                      "  <PageWidth>8.5in</PageWidth>" +
                                      "  <PageHeight>11in</PageHeight>" +
                                      "  <MarginTop>0.2in</MarginTop>" +
                                      "  <MarginLeft>0.2in</MarginLeft>" +
                                      "  <MarginRight>0.2in</MarginRight>" +
                                      "  <MarginBottom>0.5in</MarginBottom>" +
                                      "</DeviceInfo>";
            Warning[] warnings;
            string[] streams;
            //Render the report             
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);
            //Response.AddHeader("content-disposition", "attachment; filename=NorthWindCustomers." + fileNameExtension);             
            //Session["PrintId"] = null;
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo tỷ lệ L5B/L2 và L8/L2
        /// </summary>
        public ActionResult BC02()
        {
            var dayReportTypes = new Dictionary<int, string>();
            foreach (var item in Enum.GetValues(typeof(DayReportType)))
                dayReportTypes.Add((int)item, ObjectExtensions.GetEnumDescription((DayReportType)item));
            ViewBag.DayReportTypes = new SelectList(dayReportTypes, "Key", "Value");

            ViewBag.Lumpeds = LumpedRepository.GetAll();
            ViewBag.Latchs = LatchRepository.GetAll();
            return View();
        }
        public ActionResult ShowBC02(int dayReportType, int groupId, int userId, int schoolId, int majorId, int branchId, int sourceTypeId, string date, int lumpedId, int latchId, string hFromDate, string hToDate)
        {
            // Param datetime
            var dtTo = hToDate.ToDateTime() ?? DateTime.Now;
            var dtFrom = hFromDate.ToDateTime() ?? DateTime.Now;

            var listUser = StoreData.ListUser.AsReadOnly();
            if (groupId > 0) listUser = listUser.Where(c => c.GroupId == groupId).ToList().AsReadOnly();

            var infomation = "Ngày bàn giao từ ngày: {0} - đến ngày: {1}";
            switch ((DayReportType)dayReportType)
            {
                case DayReportType.Day:
                    dtTo = hToDate.ToDateTime() ?? DateTime.Now.Date;
                    dtFrom = hFromDate.ToDateTime() ?? DateTime.Now.Date;
                    break;
                case DayReportType.Week:
                    dtTo = dtFrom.AddDays(7 - (int)dtFrom.DayOfWeek);
                    dtFrom = dtFrom.AddDays(-(int)dtFrom.DayOfWeek + 1);
                    break;
                case DayReportType.Month:
                    dtTo = new DateTime(dtFrom.Year, dtFrom.Month, DateTime.DaysInMonth(dtFrom.Year, dtFrom.Month));
                    dtFrom = new DateTime(dtFrom.Year, dtFrom.Month, 1);
                    infomation = "Tháng: " + dtFrom.Month + " - " + infomation;
                    break;
                case DayReportType.Year:
                    dtTo = new DateTime(dtFrom.Year, 12, 31);
                    dtFrom = new DateTime(dtFrom.Year, 12, 1);
                    infomation = "Năm: " + dtFrom.Year + " - " + infomation;
                    break;
                case DayReportType.Latch:
                    var latch = LatchRepository.GetInfo(latchId);
                    if (latch != null)
                    {
                        dtTo = latch.EndDate.Date;
                        dtFrom = latch.StartDate.Date;
                        infomation = "Chốt: " + latch.Name + " - " + infomation;
                    }
                    break;
                case DayReportType.Lumped:
                    var lumped = LumpedRepository.GetInfo(lumpedId);
                    if (lumped != null)
                    {
                        dtTo = lumped.EndDate.Date;
                        dtFrom = lumped.StartDate.Date;
                        infomation = "Gộp: " + lumped.Name + " - " + infomation;
                    }
                    break;
            }

            if (dtTo == DateTime.MinValue || dtTo > DateTime.Now.Date) dtTo = DateTime.Now.Date;
            if (dtFrom == DateTime.MinValue || dtFrom > DateTime.Now.Date) dtFrom = DateTime.Now.Date;
            var handoverToDate = dtTo;
            var handoverFromDate = dtFrom;
            handoverToDate = handoverToDate.AddDays(1).AddSeconds(-1);

            // Load & filter data
            var dateTime = date.ToDateTime() ?? DateTime.Now.Date;
            var lstData = TmpJobReportRepository.GetAllBC300(dateTime) ?? new List<TmpJobReportBC300Info>();
            if (userId > 0) lstData = lstData.Where(c => c.UserId == userId).ToList();
            if (majorId > 0) lstData = lstData.Where(c => c.MajorId == majorId).ToList();
            if (schoolId > 0) lstData = lstData.Where(c => c.SchoolId == schoolId).ToList();
            if (branchId > 0) lstData = lstData.Where(c => c.BranchId == branchId).ToList();
            if (sourceTypeId > 0) lstData = lstData.Where(c => c.SourceTypeId == sourceTypeId).ToList();
            if (!hFromDate.IsStringNullOrEmpty() || !hToDate.IsStringNullOrEmpty())
            {
                infomation = string.Format(infomation, dtFrom.ToString("dd/MM/yyyy"), dtTo.ToString("dd/MM/yyyy"));
                lstData = lstData
                    .Where(c => c.HandoverDate >= handoverFromDate)
                    .Where(c => c.HandoverDate <= handoverToDate)
                    .ToList();
            }
            else if ((DayReportType)dayReportType == DayReportType.Lumped || (DayReportType)dayReportType == DayReportType.Latch)
            {
                infomation = string.Format(infomation, dtFrom.ToString("dd/MM/yyyy"), dtTo.ToString("dd/MM/yyyy"));
                lstData = lstData
                    .Where(c => c.HandoverDate >= handoverFromDate)
                    .Where(c => c.HandoverDate <= handoverToDate)
                    .ToList();
            }
            else infomation = "Ngày xem báo cáo: " + dateTime.ToString("dd/MM/yyyy");

            var sourceTypes = StoreData.ListSourceType
                .Where(c => c.SourceTypeId != (int)SourceType.ReUse)
                .Where(c => !c.Name.IsStringNullOrEmpty())
                .ToList();
            var listDataSource = new List<BC300Model>();
            foreach (var id in lstData.Select(c => c.UserId).Distinct())
            {
                var user = listUser.FirstOrDefault(p => p.UserID == id);
                if (user == null) continue;

                foreach (var sourceType in sourceTypes)
                {
                    var entity = new BC300Model
                                       {
                                           Level2 = 0,
                                           Level8 = 0,
                                           Level5B = 0,
                                           User = user.FullName,
                                           Group = user.GroupName,
                                           SourceType = sourceType.Code,
                                           SourceTypeId = sourceType.SourceTypeId,
                                       };
                    listDataSource.Add(entity);
                }
            }

            foreach (var item in lstData)
            {
                // User
                var user = StoreData.ListUser.FirstOrDefault(c => c.UserID == item.UserId) ?? UserRepository.GetInfo(item.UserId);
                if (user == null) continue;

                // SourceType
                var sourceType = sourceTypes.FirstOrDefault(c => c.SourceTypeId == item.SourceTypeId);
                if (sourceType == null) continue;

                // List temp
                var listTemp = lstData
                    .Where(c => c.UserId == item.UserId)
                    .Where(c => c.SourceTypeId == sourceType.SourceTypeId)
                    .ToList();

                // Create entity
                var entity = listDataSource
                    .Where(c => c.User == user.FullName)
                    .Where(c => c.Group == user.GroupName)
                   .Where(c => c.SourceTypeId == sourceType.SourceTypeId)
                    .FirstOrDefault();
                if (entity != null)
                {
                    entity.Level2 = listTemp.Where(c => c.LevelId >= (int)LevelType.L2).Sum(c => c.Count);
                    entity.Level8 = listTemp.Where(c => c.LevelId >= (int)LevelType.L8).Sum(c => c.Count);
                    entity.Level5B = listTemp.Where(c => c.LevelId >= (int)LevelType.L5B).Sum(c => c.Count);
                }
            }

            // Tính tổng
            const string userSum = "Tổng";
            var groupSum = string.Empty;
            foreach (var sourceType in sourceTypes)
            {
                if (sourceTypeId > 0 && sourceTypeId != sourceType.SourceTypeId) continue;
                var listTemp = lstData.Where(c => c.SourceTypeId == sourceType.SourceTypeId).ToList();

                listDataSource.Insert(0, new BC300Model
                {
                    User = userSum,
                    Group = groupSum,
                    SourceType = sourceType.Code,
                    SourceTypeId = sourceType.SourceTypeId,
                    Level2 = listTemp.Where(c => c.LevelId >= (int)LevelType.L2).Sum(c => c.Count),
                    Level8 = listTemp.Where(c => c.LevelId >= (int)LevelType.L8).Sum(c => c.Count),
                    Level5B = listTemp.Where(c => c.LevelId >= (int)LevelType.L5B).Sum(c => c.Count),
                });
            }

            // Tính trung bình
            var groups = listDataSource.Where(c => !c.Group.IsStringNullOrEmpty()).Select(c => c.Group).Distinct().ToList();
            foreach (var group in groups)
            {
                const string userTB = "Trung bình";
                foreach (var sourceType in sourceTypes)
                {
                    if (sourceTypeId > 0 && sourceTypeId != sourceType.SourceTypeId) continue;
                    listDataSource.Add(new BC300Model
                    {
                        User = userTB,
                        Group = group,
                        SourceType = sourceType.Code,
                        SourceTypeId = sourceType.SourceTypeId,
                        Level2 = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.SourceTypeId == sourceType.SourceTypeId).Average(c => c.Level2), 1),
                        Level8 = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.SourceTypeId == sourceType.SourceTypeId).Average(c => c.Level8), 1),
                        Level5B = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.SourceTypeId == sourceType.SourceTypeId).Average(c => c.Level5B), 1),
                    });
                }
            }

            listDataSource.RemoveAll(c => c.SourceType.IsStringNullOrEmpty());
            listDataSource = listDataSource.OrderBy(c => c.SourceTypeId).ToList();
            var reportDataSource = new ReportDataSource("TmpJobReportBC300", listDataSource);
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC02.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", infomation));
            localReport.DataSources.Add(reportDataSource);
            string mimeType;
            string encoding;
            string fileNameExtension;
            const string reportType = "pdf";
            const string deviceInfo = "<DeviceInfo>" +
                                       "  <OutputFormat>PDF</OutputFormat>" +
                                       "  <PageWidth>8.5in</PageWidth>" +
                                       "  <PageHeight>11in</PageHeight>" +
                                       "  <MarginTop>0.5in</MarginTop>" +
                                       "  <MarginLeft>0.2in</MarginLeft>" +
                                       "  <MarginRight>0.2in</MarginRight>" +
                                       "  <MarginBottom>1in</MarginBottom>" +
                                       "</DeviceInfo>";
            string[] streams;
            Warning[] warnings;
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo nghiệm thu MO
        /// </summary>
        public ActionResult BC03()
        {
            return View();
        }
        public ActionResult ShowBC03(string from, string to, int reportType)
        {
            // Param
            var branchId = UserContext.GetDefaultBranch();
            var dtFrom = from.ToDateTime() ?? DateTime.Now; dtFrom = dtFrom.Date;
            var dtTo = to.ToDateTime() ?? DateTime.Now; dtTo = dtTo.Date.AddDays(1).AddSeconds(-1);

            // Filter
            var lstContacts = ContactRepository.GetBC03(dtFrom, dtTo) ?? new List<ContactInfo>();
            lstContacts = lstContacts.Where(c => c.BranchId == branchId).ToList();

            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC03.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", "(Từ ngày: " + dtFrom.ToString("dd/MM/yyyy") + " - Đến ngày: " + dtTo.ToString("dd/MM/yyyy") + ")"));

            var lstData = new List<BC06Model>();
            foreach (var info in lstContacts)
            {
                var contactLevel = ContactLevelInfoRepository.GetInfo(info.Id) ?? new ContactLevelInfo();
                var objModel = new BC06Model
                                   {
                                       Email = info.Email,
                                       Mobile = info.Code,
                                       Fullname = info.Fullname,
                                       LocationName = info.Address,
                                       Level = Enum.GetName(typeof(LevelType), info.LevelId),
                                       SourceTypeName = Enum.GetName(typeof(SourceType), info.TypeId),
                                       HandoverDate = info.HandoverDate != null ? info.HandoverDate.Value.ToString("dd/MM/yyyy") : string.Empty,
                                       SchoolName = contactLevel.SchoolGrad.IsStringNullOrEmpty() ? contactLevel.SchoolName : contactLevel.SchoolGrad,
                                       HandoverDistributorDate = info.HandoverDistributorDate != null
                                                                     ? info.HandoverDistributorDate.Value.ToString("dd/MM/yyyy")
                                                                     : info.RegisteredDate != null
                                                                           ? info.RegisteredDate.Value.ToString("dd/MM/yyyy")
                                                                           : string.Empty,
                                   };

                // Phone
                //var phones = PhoneRepository.GetByContact(info.Id);
                //if (phones != null)
                //{
                //    var phoneEntity = phones.FirstOrDefault(phone => phone.IsPrimary > 0) ?? phones.FirstOrDefault();
                //    if (phoneEntity != null) objModel.Mobile = phoneEntity.PhoneNumber;
                //}

                // Major
                if (contactLevel.Majors.IsStringNullOrEmpty())
                {
                    var major = StoreData.ListMajor.FirstOrDefault(c => c.MajorId == info.MajorId) ??
                                MajorRepository.GetInfo(info.MajorId);
                    if (major != null) objModel.MajorName = major.Name;
                }
                else
                {
                    var strMajor = StoreData.GetAllMajor();
                    if (contactLevel.Majors == strMajor)
                    {
                        objModel.MajorName = "Tất cả";
                    }
                    else
                    {
                        var arrMajorId = contactLevel.Majors.Split(',');
                        foreach (var majorId in arrMajorId.Select(c => c.ToInt32()))
                        {
                            var major = StoreData.ListMajor.FirstOrDefault(c => c.MajorId == majorId) ??
                                        MajorRepository.GetInfo(majorId);
                            if (major != null)
                                objModel.MajorName += objModel.MajorName.IsStringNullOrEmpty()
                                                          ? major.Name
                                                          : "," + major.Name;
                        }
                    }
                }

                // Location
                if (objModel.LocationName.IsStringNullOrEmpty() && info.LocationId.HasValue)
                {
                    var location = StoreData.ListLocation.FirstOrDefault(c => info.LocationId != null && c.LocationId == info.LocationId.Value) ??
                                   LocationRepository.GetInfo(info.LocationId.Value);
                    if (location != null) objModel.LocationName = location.Name;
                }

                // StatusCare
                var statusCare = StoreData.ListStatusCare.FirstOrDefault(c => c.Id == info.StatusCareId);
                if (statusCare != null) objModel.StatusCare = statusCare.Name;

                // StatusMap
                var statusMap = StoreData.ListStatusMap.FirstOrDefault(c => c.Id == info.StatusMapId) ?? StatusMapRepository.GetInfo(info.StatusMapId);
                if (statusMap != null) objModel.StatusMap = statusMap.Name;

                // Notes
                if (info.CallInfo.IsStringNullOrEmpty())
                {
                    var callHistories = CallHistoryRepository.GetAllByContactId(info.Id);
                    if (!callHistories.IsNullOrEmpty()) objModel.Notes = callHistories.Last().CallCenterInfo;
                }
                else objModel.Notes = info.CallInfo;

                // SourceTypeName
                if (objModel.SourceTypeName == Enum.GetName(typeof(SourceType), SourceType.ReUse))
                    objModel.SourceTypeName = "Tái sử dụng";

                // Channel
                if (objModel.SourceTypeName == Enum.GetName(typeof(SourceType), SourceType.MO))
                {
                    var channel = StoreData.ListChannel.FirstOrDefault(c => c.ChannelId == info.ChannelId) ?? ChannelRepository.GetInfo(info.ChannelId);
                    if (channel != null) objModel.ChannelName = channel.Name;
                }
                else if (objModel.SourceTypeName == Enum.GetName(typeof(SourceType), SourceType.CC))
                {
                    objModel.ChannelName = contactLevel.CollaboratorName;
                }
                else
                {
                    if (info.ChannelId == 1) objModel.ChannelName = contactLevel.CollaboratorName;
                    if (objModel.ChannelName.IsStringNullOrEmpty())
                    {
                        var channel = StoreData.ListChannel.FirstOrDefault(c => c.ChannelId == info.ChannelId) ?? ChannelRepository.GetInfo(info.ChannelId);
                        if (channel != null) objModel.ChannelName = channel.Name;
                    }
                }

                // School
                var school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == info.SchoolId) ?? SchoolRepository.GetInfo(info.SchoolId);
                objModel.School = school != null ? school.Name : string.Empty;

                // School Care
                school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == info.SchoolCare) ?? SchoolRepository.GetInfo(info.SchoolCare);
                objModel.SchoolCare = school != null ? school.Name : string.Empty;

                // Consultant
                var consultant = StoreData.ListUser.FirstOrDefault(c => c.UserID == info.UserId) ?? UserRepository.GetInfo(info.UserId);
                if (consultant != null) objModel.UserName = consultant.FullName;

                lstData.Add(objModel);
            }
            var reportDataSource = new ReportDataSource("BC06", lstData);
            localReport.DataSources.Add(reportDataSource);

            string[] streams;
            Warning[] warnings;
            string mimeType, encoding, fileNameExtension, type = "pdf";
            switch (reportType)
            {
                case (int)ReportType.Pdf:
                    type = "pdf";
                    break;
                case (int)ReportType.Excel:
                    type = "excel";
                    break;
            }
            //Render the report             
            var renderedBytes = localReport.Render(type, string.Empty, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);

            switch (reportType)
            {
                case (int)ReportType.Pdf:
                    return File(renderedBytes, mimeType);
                case (int)ReportType.Excel:
                    return File(renderedBytes, mimeType, "BC03_" + dtFrom.ToString("ddMMyyyy") + ".xls");
            }
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo khối lượng công việc
        /// </summary>
        public ActionResult BC04()
        {
            return View();
        }
        public ActionResult ShowBC04(int groupId, int userId, int schoolId, int majorId, int branchId, string from, string to)
        {
            // Param datetime
            var dtFrom = DateTime.ParseExact(from, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            var dtTo = DateTime.ParseExact(to, "dd/MM/yyyy", CultureInfo.InvariantCulture).AddDays(1).AddSeconds(-1);

            var listUser = StoreData.ListUser.AsReadOnly();
            if (groupId > 0) listUser = listUser.Where(c => c.GroupId == groupId).ToList().AsReadOnly();

            // Load & filter data
            var lstDataTemp = TmpJobReportRepository.GetAllBC04(dtFrom, dtTo) ?? new List<TmpJobReportBC04Info>();
            lstDataTemp = lstDataTemp
                .Where(c => c.LevelId != (int)LevelType.L0)
                .Where(c => c.LevelId != (int)LevelType.L6)
                .Where(c => c.LevelId != (int)LevelType.L9)
                .ToList();
            if (userId > 0) lstDataTemp = lstDataTemp.Where(c => c.UserId == userId).ToList();
            if (majorId > 0) lstDataTemp = lstDataTemp.Where(c => c.MajorId == majorId).ToList();
            if (schoolId > 0) lstDataTemp = lstDataTemp.Where(c => c.SchoolId == schoolId).ToList();
            if (branchId > 0) lstDataTemp = lstDataTemp.Where(c => c.BranchId == branchId).ToList();

            var listDataSource = new List<BC04Model>();
            var levels = StoreData.ListLevel
                .Where(c => c.LevelId != (int)LevelType.L0)
                .Where(c => c.LevelId != (int)LevelType.L6)
                .Where(c => c.LevelId != (int)LevelType.L9)
                .Where(c => !c.Name.IsStringNullOrEmpty())
                .ToList();
            lstDataTemp = lstDataTemp.Where(c => levels.Exists(p => p.LevelId == c.LevelId)).ToList();
            var lstData = new List<TmpJobReportBC04Info>();
            foreach (var item in lstDataTemp)
            {
                var user = StoreData.ListUser.FirstOrDefault(c => c.UserID == item.UserId);
                if (user == null) continue;
                if (groupId > 0 && user.GroupId != groupId) continue;
                lstData.Add(item);
            }

            // select danh sach contact co hen nhung chua gọi
            foreach (var itemUserId in lstData.Select(c => c.UserId).Distinct())
            {
                var listAppointment = ContactRepository.ContactReportAppointment(itemUserId, branchId, dtFrom, dtTo) ?? new List<ContactAppointmentInfo>();
                var user = StoreData.ListUser.FirstOrDefault(c => c.UserID == itemUserId);
                if (user == null) continue;
                if (groupId > 0 && user.GroupId != groupId) continue;

                foreach (var level in levels)
                {
                    var itemAppointment = listAppointment.FirstOrDefault(c => c.LevelId == level.LevelId);
                    var entity = new BC04Model
                                     {
                                         HandoverCount = 0,
                                         Level = level.Name,
                                         CompleteInCount = 0,
                                         CompleteOutCount = 0,
                                         User = user.FullName,
                                         Group = user.GroupName,
                                         LevelId = level.LevelId,
                                         DateTime = dtFrom.ToString("dd/MM/yyyy"),
                                         Type = level.LevelId == (int)LevelType.L1 ? "Chăm sóc lần đầu" : "Chăm sóc lại",
                                         NotCompleteCount = itemAppointment == null ? 0 : itemAppointment.NotCompleteCount,
                                     };
                    listDataSource.Add(entity);
                }
            }

            foreach (var item in lstData.OrderByDescending(c => c.Type))
            {
                var user = listUser.FirstOrDefault(p => p.UserID == item.UserId);
                if (user == null) continue;
                if (groupId > 0 && user.GroupId != groupId) continue;

                // Type
                var type = item.LevelId == (int)LevelType.L1 ? "Chăm sóc lần đầu" : "Chăm sóc lại";

                // Level
                var level = levels.FirstOrDefault(p => p.LevelId == item.LevelId);
                if (level == null) continue;
                var levelName = level.Name;

                var entity = listDataSource
                    .Where(c => c.Type == type)
                    .Where(c => c.User == user.FullName)
                    .Where(c => c.Group == user.GroupName)
                    .FirstOrDefault(c => c.Level == levelName);
                if (entity != null)
                {
                    entity.HandoverCount += item.HandoverCount;
                    entity.CompleteInCount += item.CompleteInCount;
                    entity.CompleteOutCount += item.CompleteOutCount;
                }

            }
            listDataSource = listDataSource.OrderBy(c => c.User).ToList();

            // Tính tổng
            var groupSum = string.Empty;
            const string userSum = "Tổng";
            foreach (var level in levels)
            {
                var listTemp = lstData.Where(c => c.LevelId == level.LevelId).ToList();

                listDataSource.Insert(0, new BC04Model
                {
                    User = userSum,
                    Group = groupSum,
                    Level = level.Name,
                    LevelId = level.LevelId,
                    DateTime = dtFrom.ToString("dd/MM/yyyy"),
                    Type = level.LevelId == (int)LevelType.L1 ? "Chăm sóc lần đầu" : "Chăm sóc lại",
                    HandoverCount = listTemp.IsNullOrEmpty() ? 0 : listTemp.Sum(c => c.HandoverCount),
                    CompleteInCount = listTemp.IsNullOrEmpty() ? 0 : listTemp.Sum(c => c.CompleteInCount),
                    CompleteOutCount = listTemp.IsNullOrEmpty() ? 0 : listTemp.Sum(c => c.CompleteOutCount),
                    NotCompleteCount = listDataSource.IsNullOrEmpty() ? 0 : listDataSource.Where(c => c.LevelId == level.LevelId).Sum(c => c.NotCompleteCount),
                });
            }

            // Tính trung bình
            var groups = listDataSource.Where(c => !c.Group.IsStringNullOrEmpty()).Select(c => c.Group).Distinct().ToList();
            foreach (var group in groups)
            {
                const string userTB = "Trung bình";
                foreach (var level in levels)
                {
                    listDataSource.Add(new BC04Model
                    {
                        User = userTB,
                        Group = group,
                        Level = level.Name,
                        LevelId = level.LevelId,
                        DateTime = dtFrom.ToString("dd/MM/yyyy"),
                        Type = level.LevelId == (int)LevelType.L1 ? "Chăm sóc lần đầu" : "Chăm sóc lại",
                        HandoverCount = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.LevelId == level.LevelId).Average(c => c.HandoverCount), 2),
                        CompleteInCount = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.LevelId == level.LevelId).Average(c => c.CompleteInCount), 2),
                        CompleteOutCount = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.LevelId == level.LevelId).Average(c => c.CompleteOutCount), 2),
                        NotCompleteCount = Math.Round(listDataSource.Where(c => c.Group == group).Where(c => c.LevelId == level.LevelId).Average(c => c.NotCompleteCount), 2),
                    });
                }
            }

            var reportDataSource = new ReportDataSource("BC04", listDataSource);
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC04.rdlc") };
            localReport.SetParameters(new ReportParameter("FromDate", dtFrom.ToString("dd/MM/yyyy")));
            localReport.SetParameters(new ReportParameter("ToDate", dtTo.ToString("dd/MM/yyyy")));
            localReport.DataSources.Add(reportDataSource);
            string mimeType;
            string encoding;
            string fileNameExtension;
            const string reportType = "pdf";
            const string deviceInfo = "<DeviceInfo>" +
                                       "  <OutputFormat>PDF</OutputFormat>" +
                                       "  <PageWidth>8.5in</PageWidth>" +
                                       "  <PageHeight>11in</PageHeight>" +
                                       "  <MarginTop>0.2in</MarginTop>" +
                                       "  <MarginLeft>0.2in</MarginLeft>" +
                                       "  <MarginRight>0.2in</MarginRight>" +
                                       "  <MarginBottom>0.2in</MarginBottom>" +
                                       "</DeviceInfo>";
            string[] streams;
            Warning[] warnings;
            localReport.ShowDetailedSubreportMessages = false;
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo nghiệm thu tổng hợp
        /// </summary>
        public ActionResult BC05()
        {
            return View();
        }
        public ActionResult ShowBC05(int groupId, int userId, int branchId, string date)
        {
            // Param datetime
            var dtTo = string.IsNullOrEmpty(date) ? DateTime.Now.Date : DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            var dtFrom = string.IsNullOrEmpty(date) ? DateTime.Now.Date : DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);

            var listUser = StoreData.ListUser.AsReadOnly();
            if (groupId > 0) listUser = listUser.Where(c => c.GroupId == groupId).ToList().AsReadOnly();

            // Load & filter data
            var lstData = TmpJobReportRepository.GetAllBC05(dtTo) ?? new List<TmpJobReportBC05Info>();
            if (userId > 0) lstData = lstData.Where(c => c.UserId == userId).ToList();
            if (branchId > 0) lstData = lstData.Where(c => c.BranchId == branchId).ToList();

            var listDataSource = new List<BC05Model>();

            // Tổng
            var schools = lstData.Select(c => c.SchoolId).Distinct();
            foreach (var schoolId in schools)
            {
                var lstTemp = lstData.Where(c => c.SchoolId == schoolId).ToList();
                var objModel = new BC05Model
                {
                    Consultant = " Tổng",
                    KDDT = lstTemp.Sum(c => c.KDDT),
                    KLLD = lstTemp.Sum(c => c.KLLD),
                    SaiSo = lstTemp.Sum(c => c.SaiSo),
                    KNM = lstTemp.Sum(c => c.KNM),
                    KhacVung = lstTemp.Sum(c => c.KhacVung),
                    TotalHandover = lstTemp.Sum(c => c.HandoverCount),
                };
                objModel.TotalReturn = objModel.KDDT + objModel.KLLD + objModel.KhacVung + objModel.SaiSo + objModel.KNM;
                objModel.ThucNhan = objModel.TotalHandover - objModel.TotalReturn;
                if (objModel.TotalHandover > 0) objModel.TotalPercentage = (double)objModel.TotalReturn / objModel.TotalHandover;

                // School
                var school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == schoolId) ?? SchoolRepository.GetInfo(schoolId);
                objModel.SchoolName = school != null ? school.Name : "Chưa biết";
                listDataSource.Add(objModel);
            }

            foreach (var info in lstData)
            {
                // User
                var user = listUser.FirstOrDefault(p => p.UserID == info.UserId);
                var consultantName = user == null ? string.Empty : user.FullName;

                // School
                var school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == info.SchoolId) ??
                             SchoolRepository.GetInfo(info.SchoolId);
                var schoolName = school != null ? school.Name : "Chưa biết";

                if (consultantName.IsStringNullOrEmpty() || schoolName.IsStringNullOrEmpty()) continue;
                var objModel = listDataSource.Where(c => c.Consultant == consultantName).FirstOrDefault(c => c.SchoolName == schoolName);
                if (objModel == null)
                {
                    objModel = new BC05Model
                                   {
                                       KNM = info.KNM,
                                       KDDT = info.KDDT,
                                       KLLD = info.KLLD,
                                       SaiSo = info.SaiSo,
                                       SchoolName = schoolName,
                                       KhacVung = info.KhacVung,
                                       Consultant = consultantName,
                                       TotalHandover = info.HandoverCount,
                                       TotalReturn = info.KDDT + info.KLLD + info.KhacVung + info.SaiSo + info.KNM,
                                       ThucNhan = info.HandoverCount - (info.KDDT + info.KLLD + info.KhacVung + info.SaiSo + info.KNM),
                                   };
                    if (objModel.TotalHandover > 0)
                        objModel.TotalPercentage = (double)objModel.TotalReturn / objModel.TotalHandover;
                    listDataSource.Add(objModel);
                }
                else
                {
                    objModel.KNM += info.KNM;
                    objModel.KDDT += info.KDDT;
                    objModel.KLLD += info.KLLD;
                    objModel.SaiSo += info.SaiSo;
                    objModel.KhacVung += info.KhacVung;
                    objModel.TotalHandover += info.HandoverCount;
                    objModel.TotalReturn = objModel.KDDT + objModel.KLLD + objModel.KhacVung + objModel.SaiSo + objModel.KNM;
                    objModel.ThucNhan = objModel.TotalHandover - objModel.TotalReturn;
                    if (objModel.TotalHandover > 0) objModel.TotalPercentage = (double)objModel.TotalReturn / objModel.TotalHandover;
                }
            }
            foreach (var item in listDataSource.Where(c => c.SchoolName == "Tất cả")) item.SchoolName = "Chưa biết";
            var reportDataSource = new ReportDataSource("BC05", listDataSource.OrderBy(c => c.SchoolName).ToList());
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC05.rdlc") };
            localReport.SetParameters(new ReportParameter("QueryTime", string.Format(dtFrom.ToString("dd/MM/yyyy"))));
            localReport.DataSources.Add(reportDataSource);
            const string reportType = "pdf";
            string mimeType;
            string encoding;
            string fileNameExtension;
            //The DeviceInfo settings should be changed based on the reportType             
            //http://msdn2.microsoft.com/en-us/library/ms155397.aspx             
            const string deviceInfo = "<DeviceInfo>" +
                                      "  <OutputFormat>PDF</OutputFormat>" +
                                      "  <PageWidth>11.69in</PageWidth>" +
                                      "  <PageHeight>8.27in</PageHeight>" +
                                      "  <MarginTop>0.2in</MarginTop>" +
                                      "  <MarginLeft>0.2in</MarginLeft>" +
                                      "  <MarginRight>0.2in</MarginRight>" +
                                      "  <MarginBottom>0.2in</MarginBottom>" +
                                      "</DeviceInfo>";
            Warning[] warnings;
            string[] streams;
            //Render the report             
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);
            //Response.AddHeader("content-disposition", "attachment; filename=NorthWindCustomers." + fileNameExtension);             
            //Session["PrintId"] = null;
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo nghiệm thu tổng hợp cho đội lọc
        /// </summary>
        public ActionResult BC07()
        {
            return View();
        }
        public ActionResult ShowBC07(int branchId, string date)
        {
            // Param datetime
            var dtTo = string.IsNullOrEmpty(date) ? DateTime.Now.Date : DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            var dtFrom = string.IsNullOrEmpty(date) ? DateTime.Now.Date : DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);

            // Load & filter data
            var lstData = TmpJobReportRepository.GetAllBC07(dtTo) ?? new List<TmpJobReportBC07Info>();
            if (branchId > 0) lstData = lstData.Where(c => c.BranchId == branchId).ToList();

            var listDataSource = new List<BC07Model>();
            foreach (var info in lstData)
            {
                // School
                var school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == info.SchoolId) ??
                             SchoolRepository.GetInfo(info.SchoolId);
                var schoolName = school != null ? school.Name : "Chưa biết";
                var objModel = listDataSource.FirstOrDefault(c => c.SchoolName == schoolName);
                if (objModel == null)
                {
                    objModel = new BC07Model
                                   {
                                       KDDT = info.KDDT,
                                       KLLD = info.KLLD,
                                       SaiSo = info.SaiSo,
                                       Duplicate = info.Trung,
                                       KhacVung = info.KhacVung,
                                       TotalHandover = info.HandoverCount,
                                       SchoolName = school != null ? school.Name : "Chưa biết",
                                       TotalReturn = info.KDDT + info.KLLD + info.KhacVung + info.SaiSo + info.Trung,
                                       ThucNhan = info.HandoverCount - (info.KDDT + info.KLLD + info.KhacVung + info.SaiSo + info.Trung),
                                   };
                    if (objModel.TotalHandover > 0) objModel.TotalPercentage = (double)objModel.TotalReturn / objModel.TotalHandover;
                    listDataSource.Add(objModel);
                }
                else
                {
                    objModel.KDDT += info.KDDT;
                    objModel.KLLD += info.KLLD;
                    objModel.SaiSo += info.SaiSo;
                    objModel.Duplicate += info.Trung;
                    objModel.KhacVung += info.KhacVung;
                    objModel.TotalHandover += info.HandoverCount;
                    objModel.TotalReturn += info.KDDT + info.KLLD + info.KhacVung + info.SaiSo + info.Trung;
                    objModel.ThucNhan += info.HandoverCount - (info.KDDT + info.KLLD + info.KhacVung + info.SaiSo + info.Trung);
                    if (objModel.TotalHandover > 0) objModel.TotalPercentage = (double)objModel.TotalReturn / objModel.TotalHandover;
                }
            }
            foreach (var item in listDataSource.Where(c => c.SchoolName == "Tất cả")) item.SchoolName = "Chưa biết";
            var reportDataSource = new ReportDataSource("BC05", listDataSource.OrderBy(c => c.SchoolName).ToList());
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC07.rdlc") };
            localReport.SetParameters(new ReportParameter("QueryTime", string.Format(dtFrom.ToString("dd/MM/yyyy"))));
            localReport.DataSources.Add(reportDataSource);
            const string reportType = "pdf";
            string mimeType;
            string encoding;
            string fileNameExtension;
            //The DeviceInfo settings should be changed based on the reportType             
            //http://msdn2.microsoft.com/en-us/library/ms155397.aspx             
            const string deviceInfo = "<DeviceInfo>" +
                                      "  <OutputFormat>PDF</OutputFormat>" +
                                      "  <PageWidth>11.69in</PageWidth>" +
                                      "  <PageHeight>8.27in</PageHeight>" +
                                      "  <MarginTop>0.2in</MarginTop>" +
                                      "  <MarginLeft>0.2in</MarginLeft>" +
                                      "  <MarginRight>0.2in</MarginRight>" +
                                      "  <MarginBottom>0.2in</MarginBottom>" +
                                      "</DeviceInfo>";
            Warning[] warnings;
            string[] streams;
            //Render the report             
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);
            //Response.AddHeader("content-disposition", "attachment; filename=NorthWindCustomers." + fileNameExtension);             
            //Session["PrintId"] = null;
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo nghiệm thu kết quả L1
        /// </summary>
        public ActionResult BC08()
        {
            return View();
        }
        public ActionResult ShowBC08(int branchId, string date, int reportType)
        {
            // Param datetime
            var dtTo = string.IsNullOrEmpty(date) ? DateTime.Now.Date : DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            var dtFrom = string.IsNullOrEmpty(date) ? DateTime.Now.Date : DateTime.ParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture);

            // Load & filter data
            var lstData = TmpJobReportRepository.GetAllBC08(dtTo) ?? new List<TmpJobReportBC08Info>();
            if (branchId > 0) lstData = lstData.Where(c => c.BranchId == branchId).ToList();

            var listDataSource = new List<BC08Model>();
            foreach (var info in lstData)
            {
                // School
                var import = ImportExcelRepository.GetInfo(info.ImportId);
                var importName = import != null ? (new FileInfo(import.FilePath)).Name : "Chưa biết";
                var objModel = listDataSource.FirstOrDefault(c => c.Import == importName);
                if (objModel == null)
                {
                    objModel = new BC08Model
                    {
                        Gia = info.Gia,
                        KNM = info.KNM,
                        KLLD = info.KLLD,
                        Trung = info.Trung,
                        Import = importName,
                        CaoHoc = info.CaoHoc,
                        VungKhac = info.VungKhac,
                        SinhVien = info.SinhVien,
                        NhamNguoi = info.NhamNguoi,
                        KhongNhuCau = info.KhongNhuCau,
                        L1 = info.LevelId <= 1 ? info.Amount : 0,
                        L2 = info.LevelId >= 2 ? info.Amount : 0,
                    };
                    listDataSource.Add(objModel);
                }
                else
                {
                    objModel.Gia += info.Gia;
                    objModel.KNM += info.KNM;
                    objModel.KLLD += info.KLLD;
                    objModel.Trung += info.Trung;
                    objModel.CaoHoc += info.CaoHoc;
                    objModel.VungKhac += info.VungKhac;
                    objModel.SinhVien += info.SinhVien;
                    objModel.NhamNguoi += info.NhamNguoi;
                    objModel.KhongNhuCau += info.KhongNhuCau;
                    objModel.L1 += info.LevelId <= 1 ? info.Amount : 0;
                    objModel.L2 += info.LevelId >= 2 ? info.Amount : 0;
                }
            }

            foreach (var model in listDataSource)
            {
                model.L1 = model.L1 + model.L2;
                model.NotCompleteCount = model.L1 - model.L2 - model.KLLD - model.KNM - model.Trung - model.CaoHoc -
                                         model.Gia - model.SinhVien - model.KhongNhuCau - model.VungKhac - model.NhamNguoi;
                if (model.NotCompleteCount < 0) model.NotCompleteCount = 0;

            }

            var reportDataSource = new ReportDataSource("BC08", listDataSource.OrderBy(c => c.Import).ToList());
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC08.rdlc") };
            localReport.SetParameters(new ReportParameter("QueryTime", string.Format(dtFrom.ToString("dd/MM/yyyy"))));
            localReport.DataSources.Add(reportDataSource);
            string[] streams;
            Warning[] warnings;
            string mimeType, encoding, fileNameExtension, type = "pdf";
            switch (reportType)
            {
                case (int)ReportType.Pdf:
                    type = "pdf";
                    break;
                case (int)ReportType.Excel:
                    type = "excel";
                    break;
            }

            //Render the report             
            const string deviceInfo = "<DeviceInfo>" +
                                      "  <OutputFormat>PDF</OutputFormat>" +
                                      "  <PageWidth>12in</PageWidth>" +
                                      "  <PageHeight>8.27in</PageHeight>" +
                                      "  <MarginTop>0.2in</MarginTop>" +
                                      "  <MarginLeft>0.2in</MarginLeft>" +
                                      "  <MarginRight>0.2in</MarginRight>" +
                                      "  <MarginBottom>0.2in</MarginBottom>" +
                                      "</DeviceInfo>";
            var renderedBytes = localReport.Render(type, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);

            switch (reportType)
            {
                case (int)ReportType.Pdf:
                    return File(renderedBytes, mimeType);
                case (int)ReportType.Excel:
                    return File(renderedBytes, mimeType, "BC08_" + dtFrom.ToString("ddMMyyyy") + ".xls");
            }
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo chi tiết trả lại
        /// </summary>
        public ActionResult BC06()
        {
            return View();
        }
        public ActionResult ShowBC06(string from, string to, int reportType)
        {
            // Param
            var branchId = UserContext.GetDefaultBranch();
            var dtFrom = from.ToDateTime() ?? DateTime.Now; dtFrom = dtFrom.Date;
            var dtTo = to.ToDateTime() ?? DateTime.Now; dtTo = dtTo.Date.AddDays(1).AddSeconds(-1);

            // Filter
            var lstContacts = ContactRepository.GetBC06(dtFrom, dtTo) ?? new List<ContactInfo>();
            lstContacts = lstContacts.Where(c => c.BranchId == branchId).ToList();

            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC06.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", "(Từ ngày: " + dtFrom.ToString("dd/MM/yyyy") + " - Đến ngày: " + dtTo.ToString("dd/MM/yyyy") + ")"));

            var lstData = new List<BC06Model>();
            foreach (var info in lstContacts)
            {
                var contactLevel = ContactLevelInfoRepository.GetInfo(info.Id) ?? new ContactLevelInfo();
                var objModel = new BC06Model
                                   {
                                       Email = info.Email,
                                       Fullname = info.Fullname,
                                       LocationName = info.Address,
                                       Level = Enum.GetName(typeof(LevelType), info.LevelId),
                                       SourceTypeName = Enum.GetName(typeof(SourceType), info.TypeId),
                                       HandoverDate = info.HandoverDate != null ? info.HandoverDate.Value.ToString("dd/MM/yyyy") : string.Empty,
                                       SchoolName = contactLevel.SchoolGrad.IsStringNullOrEmpty() ? contactLevel.SchoolName : contactLevel.SchoolGrad,
                                       HandoverDistributorDate = info.RegisteredDate != null ? info.RegisteredDate.Value.ToString("dd/MM/yyyy") : string.Empty,
                                   };
                if (objModel.HandoverDistributorDate.IsStringNullOrEmpty())
                    objModel.HandoverDistributorDate = info.HandoverDistributorDate != null
                                                           ? info.HandoverDistributorDate.Value.ToString("dd/MM/yyyy")
                                                           : string.Empty;

                // Phone
                var phones = PhoneRepository.GetByContact(info.Id);
                if (phones != null)
                {
                    var phoneEntity = phones.FirstOrDefault(phone => phone.IsPrimary > 0) ?? phones.FirstOrDefault();
                    if (phoneEntity != null) objModel.Mobile = phoneEntity.PhoneNumber;
                }

                // Major
                if (contactLevel.Majors.IsStringNullOrEmpty())
                {
                    var major = StoreData.ListMajor.FirstOrDefault(c => c.MajorId == info.MajorId) ??
                                MajorRepository.GetInfo(info.MajorId);
                    if (major != null) objModel.MajorName = major.Name;
                }
                else
                {
                    var strMajor = StoreData.GetAllMajor();
                    if (contactLevel.Majors == strMajor)
                    {
                        objModel.MajorName = "Tất cả";
                    }
                    else
                    {
                        var arrMajorId = contactLevel.Majors.Split(',');
                        foreach (var majorId in arrMajorId.Select(c => c.ToInt32()))
                        {
                            var major = StoreData.ListMajor.FirstOrDefault(c => c.MajorId == majorId) ??
                                        MajorRepository.GetInfo(majorId);
                            if (major != null)
                                objModel.MajorName += objModel.MajorName.IsStringNullOrEmpty()
                                                          ? major.Name
                                                          : "," + major.Name;
                        }
                    }
                }

                // Location
                if (objModel.LocationName.IsStringNullOrEmpty() && info.LocationId.HasValue)
                {
                    var location = StoreData.ListLocation.FirstOrDefault(c => info.LocationId != null && c.LocationId == info.LocationId.Value) ??
                                   LocationRepository.GetInfo(info.LocationId.Value);
                    if (location != null) objModel.LocationName = location.Name;
                }

                // StatusCare
                var statusCare = StoreData.ListStatusCare.FirstOrDefault(c => c.Id == info.StatusCareId);
                if (statusCare != null) objModel.StatusCare = statusCare.Name;

                // StatusMap
                var statusMap = StoreData.ListStatusMap.FirstOrDefault(c => c.Id == info.StatusMapId) ?? StatusMapRepository.GetInfo(info.StatusMapId);
                if (statusMap != null) objModel.StatusMap = statusMap.Name;

                // Notes
                if (info.CallInfo.IsStringNullOrEmpty())
                {
                    var callHistories = CallHistoryRepository.GetAllByContactId(info.Id);
                    if (!callHistories.IsNullOrEmpty()) objModel.Notes = callHistories.Last().CallCenterInfo;
                }
                else objModel.Notes = info.CallInfo;

                // SourceTypeName
                if (objModel.SourceTypeName == Enum.GetName(typeof(SourceType), SourceType.ReUse))
                    objModel.SourceTypeName = "Tái sử dụng";

                // Channel
                if (objModel.SourceTypeName == Enum.GetName(typeof(SourceType), SourceType.MO))
                {
                    var channel = StoreData.ListChannel.FirstOrDefault(c => c.ChannelId == info.ChannelId) ?? ChannelRepository.GetInfo(info.ChannelId);
                    if (channel != null) objModel.ChannelName = channel.Name;
                }
                else if (objModel.SourceTypeName == Enum.GetName(typeof(SourceType), SourceType.CC))
                {
                    objModel.ChannelName = contactLevel.CollaboratorName;
                }
                else
                {
                    if (info.ChannelId == 1) objModel.ChannelName = contactLevel.CollaboratorName;
                    if (objModel.ChannelName.IsStringNullOrEmpty())
                    {
                        var channel = StoreData.ListChannel.FirstOrDefault(c => c.ChannelId == info.ChannelId) ?? ChannelRepository.GetInfo(info.ChannelId);
                        if (channel != null) objModel.ChannelName = channel.Name;
                    }
                }

                // School
                var school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == info.SchoolId) ?? SchoolRepository.GetInfo(info.SchoolId);
                objModel.School = school != null ? school.Name : string.Empty;

                // School Care
                school = StoreData.ListSchool.FirstOrDefault(c => c.SchoolId == info.SchoolCare) ?? SchoolRepository.GetInfo(info.SchoolCare);
                objModel.SchoolCare = school != null ? school.Name : string.Empty;

                // Consultant
                var consultant = StoreData.ListUser.FirstOrDefault(c => c.UserID == info.UserId) ?? UserRepository.GetInfo(info.UserId);
                if (consultant != null) objModel.UserName = consultant.FullName;

                lstData.Add(objModel);
            }
            var reportDataSource = new ReportDataSource("BC06", lstData);
            localReport.DataSources.Add(reportDataSource);

            string[] streams;
            Warning[] warnings;
            string mimeType, encoding, fileNameExtension, type = "pdf";
            switch (reportType)
            {
                case (int)ReportType.Pdf:
                    type = "pdf";
                    break;
                case (int)ReportType.Excel:
                    type = "excel";
                    break;
            }
            //Render the report             
            var renderedBytes = localReport.Render(type, string.Empty, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);

            switch (reportType)
            {
                case (int)ReportType.Pdf:
                    return File(renderedBytes, mimeType);
                case (int)ReportType.Excel:
                    return File(renderedBytes, mimeType, "BC06_" + dtFrom.ToString("ddMMyyyy") + ".xls");
            }
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo tỷ lệ
        /// </summary>
        public ActionResult BC300()
        {
            var dayReportTypes = new Dictionary<int, string>();
            foreach (var item in Enum.GetValues(typeof(DayReportType)))
                dayReportTypes.Add((int)item, ObjectExtensions.GetEnumDescription((DayReportType)item));
            ViewBag.DayReportTypes = new SelectList(dayReportTypes, "Key", "Value");

            ViewBag.Lumpeds = LumpedRepository.GetAll();
            ViewBag.Latchs = LatchRepository.GetAll();
            return View();
        }
        public ActionResult ShowBC300(int dayReportType, int groupId, int userId, int schoolId, int majorId, int branchId, int sourceTypeId, string date, int lumpedId, int latchId, string hFromDate, string hToDate)
        {
            // Param datetime
            var dtTo = hToDate.ToDateTime() ?? DateTime.Now;
            var dtFrom = hFromDate.ToDateTime() ?? DateTime.Now;

            var listUser = StoreData.ListUser.AsReadOnly();
            if (groupId > 0) listUser = listUser.Where(c => c.GroupId == groupId).ToList().AsReadOnly();

            var infomation = "Ngày bàn giao từ ngày: {0} - đến ngày: {1}";
            switch ((DayReportType)dayReportType)
            {
                case DayReportType.Day:
                    dtTo = hToDate.ToDateTime() ?? DateTime.Now.Date;
                    dtFrom = hFromDate.ToDateTime() ?? DateTime.Now.Date;
                    break;
                case DayReportType.Week:
                    dtTo = dtFrom.AddDays(7 - (int)dtFrom.DayOfWeek);
                    dtFrom = dtFrom.AddDays(-(int)dtFrom.DayOfWeek + 1);
                    break;
                case DayReportType.Month:
                    dtTo = new DateTime(dtFrom.Year, dtFrom.Month, DateTime.DaysInMonth(dtFrom.Year, dtFrom.Month));
                    dtFrom = new DateTime(dtFrom.Year, dtFrom.Month, 1);
                    infomation = "Tháng: " + dtFrom.Month + " - " + infomation;
                    break;
                case DayReportType.Year:
                    dtTo = new DateTime(dtFrom.Year, 12, 31);
                    dtFrom = new DateTime(dtFrom.Year, 12, 1);
                    infomation = "Năm: " + dtFrom.Year + " - " + infomation;
                    break;
                case DayReportType.Latch:
                    var latch = LatchRepository.GetInfo(latchId);
                    if (latch != null)
                    {
                        dtTo = latch.EndDate.Date;
                        dtFrom = latch.StartDate.Date;
                        infomation = "Chốt: " + latch.Name + " - " + infomation;
                    }
                    break;
                case DayReportType.Lumped:
                    var lumped = LumpedRepository.GetInfo(lumpedId);
                    if (lumped != null)
                    {
                        dtTo = lumped.EndDate.Date;
                        dtFrom = lumped.StartDate.Date;
                        infomation = "Gộp: " + lumped.Name + " - " + infomation;
                    }
                    break;
            }

            if (dtTo == DateTime.MinValue || dtTo > DateTime.Now.Date) dtTo = DateTime.Now.Date;
            if (dtFrom == DateTime.MinValue || dtFrom > DateTime.Now.Date) dtFrom = DateTime.Now.Date;
            var handoverToDate = dtTo;
            var handoverFromDate = dtFrom;
            handoverToDate = handoverToDate.AddDays(1).AddSeconds(-1);

            // Load & filter data
            var dateTime = date.ToDateTime() ?? DateTime.Now.Date;
            var lstData = TmpJobReportRepository.GetAllBC300(dateTime) ?? new List<TmpJobReportBC300Info>();
            if (userId > 0) lstData = lstData.Where(c => c.UserId == userId).ToList();
            if (majorId > 0) lstData = lstData.Where(c => c.MajorId == majorId).ToList();
            if (schoolId > 0) lstData = lstData.Where(c => c.SchoolId == schoolId).ToList();
            if (branchId > 0) lstData = lstData.Where(c => c.BranchId == branchId).ToList();
            if (sourceTypeId > 0) lstData = lstData.Where(c => c.SourceTypeId == sourceTypeId).ToList();
            if (!hFromDate.IsStringNullOrEmpty() || !hToDate.IsStringNullOrEmpty())
            {
                infomation = string.Format(infomation, dtFrom.ToString("dd/MM/yyyy"), dtTo.ToString("dd/MM/yyyy"));
                lstData = lstData
                    .Where(c => c.HandoverDate >= handoverFromDate)
                    .Where(c => c.HandoverDate <= handoverToDate)
                    .ToList();
            }
            else if ((DayReportType)dayReportType == DayReportType.Lumped || (DayReportType)dayReportType == DayReportType.Latch)
            {
                infomation = string.Format(infomation, dtFrom.ToString("dd/MM/yyyy"), dtTo.ToString("dd/MM/yyyy"));
                lstData = lstData
                    .Where(c => c.HandoverDate >= handoverFromDate)
                    .Where(c => c.HandoverDate <= handoverToDate)
                    .ToList();
            }
            else infomation = "Ngày xem báo cáo: " + dateTime.ToString("dd/MM/yyyy");
            var listDataSource = new List<BC300Model>();

            // Tổng
            {
                var listTemp = lstData.ToList();
                var level1 = listTemp.Where(c => c.LevelId >= (int)LevelType.L1).Sum(c => c.Count);
                var level2 = listTemp.Where(c => c.LevelId >= (int)LevelType.L2).Sum(c => c.Count);
                var level3 = listTemp.Where(c => c.LevelId >= (int)LevelType.L3).Sum(c => c.Count);
                var level4 = listTemp.Where(c => c.LevelId >= (int)LevelType.L4).Sum(c => c.Count);
                var level6 = listTemp.Where(c => c.LevelId >= (int)LevelType.L6).Sum(c => c.Count);
                var level7 = listTemp.Where(c => c.LevelId >= (int)LevelType.L7).Sum(c => c.Count);
                var level8 = listTemp.Where(c => c.LevelId >= (int)LevelType.L8).Sum(c => c.Count);
                var level9 = listTemp.Where(c => c.LevelId >= (int)LevelType.L9).Sum(c => c.Count);
                var level5A = listTemp.Where(c => c.LevelId >= (int)LevelType.L5A).Sum(c => c.Count);
                var level5B = listTemp.Where(c => c.LevelId >= (int)LevelType.L5B).Sum(c => c.Count);

                var entity = new BC300Model
                {
                    User = "Tổng",
                    Group = string.Empty,
                    Name = "Tỷ lệ %(Lx/Ly)",
                    Level1 = level1 > 0 ? Math.Round((double)level1 / level1 * 100, 1) : 0,
                    Level2 = level1 > 0 ? Math.Round((double)level2 / level1 * 100, 1) : 0,
                    Level3 = level2 > 0 ? Math.Round((double)level3 / level2 * 100, 1) : 0,
                    Level4 = level3 > 0 ? Math.Round((double)level4 / level3 * 100, 1) : 0,
                    Level7 = level6 > 0 ? Math.Round((double)level7 / level6 * 100, 1) : 0,
                    Level8 = level7 > 0 ? Math.Round((double)level8 / level7 * 100, 1) : 0,
                    Level9 = level8 > 0 ? Math.Round((double)level9 / level8 * 100, 1) : 0,
                    Level6 = level5B > 0 ? Math.Round((double)level6 / level5B * 100, 1) : 0,
                    Level5A = level4 > 0 ? Math.Round((double)level5A / level4 * 100, 1) : 0,
                    Level5B = level5A > 0 ? Math.Round((double)level5B / level5A * 100, 1) : 0,
                };
                listDataSource.Add(entity);
            }

            foreach (var id in lstData.Select(c => c.UserId).Distinct())
            {
                var user = listUser.FirstOrDefault(p => p.UserID == id);
                if (user == null) continue;

                var listTemp = lstData.Where(c => c.UserId == user.UserID).ToList();
                var level1 = listTemp.Where(c => c.LevelId >= (int)LevelType.L1).Sum(c => c.Count);
                var level2 = listTemp.Where(c => c.LevelId >= (int)LevelType.L2).Sum(c => c.Count);
                var level3 = listTemp.Where(c => c.LevelId >= (int)LevelType.L3).Sum(c => c.Count);
                var level4 = listTemp.Where(c => c.LevelId >= (int)LevelType.L4).Sum(c => c.Count);
                var level6 = listTemp.Where(c => c.LevelId >= (int)LevelType.L6).Sum(c => c.Count);
                var level7 = listTemp.Where(c => c.LevelId >= (int)LevelType.L7).Sum(c => c.Count);
                var level8 = listTemp.Where(c => c.LevelId >= (int)LevelType.L8).Sum(c => c.Count);
                var level9 = listTemp.Where(c => c.LevelId >= (int)LevelType.L9).Sum(c => c.Count);
                var level5A = listTemp.Where(c => c.LevelId >= (int)LevelType.L5A).Sum(c => c.Count);
                var level5B = listTemp.Where(c => c.LevelId >= (int)LevelType.L5B).Sum(c => c.Count);

                var entity = new BC300Model
                {
                    User = user.FullName,
                    Group = user.GroupName,
                    Name = "Tỷ lệ %(Lx/Ly)",
                    Level1 = level1 > 0 ? Math.Round((double)level1 / level1 * 100, 1) : 0,
                    Level2 = level1 > 0 ? Math.Round((double)level2 / level1 * 100, 1) : 0,
                    Level3 = level2 > 0 ? Math.Round((double)level3 / level2 * 100, 1) : 0,
                    Level4 = level3 > 0 ? Math.Round((double)level4 / level3 * 100, 1) : 0,
                    Level7 = level6 > 0 ? Math.Round((double)level7 / level6 * 100, 1) : 0,
                    Level8 = level7 > 0 ? Math.Round((double)level8 / level7 * 100, 1) : 0,
                    Level9 = level8 > 0 ? Math.Round((double)level9 / level8 * 100, 1) : 0,
                    Level5A = level4 > 0 ? Math.Round((double)level5A / level4 * 100, 1) : 0,
                    Level6 = level5B > 0 ? Math.Round((double)level6 / level5B * 100, 1) : 0,
                    Level5B = level5A > 0 ? Math.Round((double)level5B / level5A * 100, 1) : 0,
                };
                listDataSource.Add(entity);

                entity = new BC300Model
                                 {
                                     Group = user.GroupName,
                                     User = user.FullName,
                                     Name = "Số lượng (contact)",
                                     Level1 = level1,
                                     Level2 = level2,
                                     Level3 = level3,
                                     Level4 = level4,
                                     Level5A = level5A,
                                     Level5B = level5B,
                                     Level6 = level6,
                                     Level7 = level7,
                                     Level8 = level8,
                                     Level9 = level9,
                                 };
                listDataSource.Add(entity);
            }

            // Trung bình
            var groups = listDataSource
                .Where(c => !c.Group.IsStringNullOrEmpty())
                .Select(c => c.Group)
                .Distinct()
                .ToList();
            foreach (var group in groups)
            {
                var listTemp = listDataSource
                    .Where(c => c.Group == group)
                    .Where(c => c.Name == "Số lượng (contact)")
                    .ToList();
                if (listTemp.IsNullOrEmpty()) continue;

                var level1 = listTemp.Sum(c => c.Level1);
                var level2 = listTemp.Sum(c => c.Level2);
                var level3 = listTemp.Sum(c => c.Level3);
                var level4 = listTemp.Sum(c => c.Level4);
                var level6 = listTemp.Sum(c => c.Level6);
                var level7 = listTemp.Sum(c => c.Level7);
                var level8 = listTemp.Sum(c => c.Level8);
                var level9 = listTemp.Sum(c => c.Level9);
                var level5A = listTemp.Sum(c => c.Level5A);
                var level5B = listTemp.Sum(c => c.Level5B);

                var entity = new BC300Model
                {
                    Group = group,
                    User = "Trung bình",
                    Name = "Tỷ lệ %(Lx/Ly)",
                    Level1 = level1 > 0 ? Math.Round(level1 / level1 * 100, 1) : 0,
                    Level2 = level1 > 0 ? Math.Round(level2 / level1 * 100, 1) : 0,
                    Level3 = level2 > 0 ? Math.Round(level3 / level2 * 100, 1) : 0,
                    Level4 = level3 > 0 ? Math.Round(level4 / level3 * 100, 1) : 0,
                    Level7 = level6 > 0 ? Math.Round(level7 / level6 * 100, 1) : 0,
                    Level8 = level7 > 0 ? Math.Round(level8 / level7 * 100, 1) : 0,
                    Level9 = level8 > 0 ? Math.Round(level9 / level8 * 100, 1) : 0,
                    Level5A = level4 > 0 ? Math.Round(level5A / level4 * 100, 1) : 0,
                    Level6 = level5B > 0 ? Math.Round(level6 / level5B * 100, 1) : 0,
                    Level5B = level5A > 0 ? Math.Round(level5B / level5A * 100, 1) : 0,
                };
                listDataSource.Add(entity);
            }

            var listTempTotal = listDataSource
                   .Where(c => c.Name == "Số lượng (contact)")
                   .ToList();
            var entityTotal = new BC300Model
            {
                User = "Tổng",
                Group = string.Empty,
                Name = "Số lượng (contact)",
                Level1 = listTempTotal.Sum(c => c.Level1),
                Level2 = listTempTotal.Sum(c => c.Level2),
                Level3 = listTempTotal.Sum(c => c.Level3),
                Level4 = listTempTotal.Sum(c => c.Level4),
                Level6 = listTempTotal.Sum(c => c.Level6),
                Level7 = listTempTotal.Sum(c => c.Level7),
                Level8 = listTempTotal.Sum(c => c.Level8),
                Level9 = listTempTotal.Sum(c => c.Level9),
                Level5A = listTempTotal.Sum(c => c.Level5A),
                Level5B = listTempTotal.Sum(c => c.Level5B),
            };
            listDataSource.Insert(1, entityTotal);

            if (listDataSource.Count <= 2) listDataSource.Clear();
            var reportDataSource = new ReportDataSource("TmpJobReportBC300", listDataSource);
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC300.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", infomation));
            localReport.DataSources.Add(reportDataSource);
            string mimeType;
            string encoding;
            string fileNameExtension;
            const string reportType = "pdf";
            const string deviceInfo = "<DeviceInfo>" +
                                       "  <OutputFormat>PDF</OutputFormat>" +
                                       "  <PageWidth>11in</PageWidth>" +
                                       "  <PageHeight>8.5in</PageHeight>" +
                                       "  <MarginTop>0.5in</MarginTop>" +
                                       "  <MarginLeft>0.2in</MarginLeft>" +
                                       "  <MarginRight>0.2in</MarginRight>" +
                                       "  <MarginBottom>1in</MarginBottom>" +
                                       "</DeviceInfo>";
            string[] streams;
            Warning[] warnings;
            var renderedBytes = localReport.Render(
                reportType,
                deviceInfo,
                out mimeType,
                out encoding,
                out fileNameExtension,
                out streams,
                out warnings);
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo tình trạng kết nối của Contact L1
        /// </summary>
        public ActionResult BC09()
        {
            return View();
        }
        public ActionResult ShowBC09()
        {
            // Param
            var lstData = new List<BC06Model>();
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC09.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", "(Từ ngày: " + DateTime.Now.ToString("dd/MM/yyyy") + " - Đến ngày: " + DateTime.Now.AddDays(10).ToString("dd/MM/yyyy") + ")"));

            var reportDataSource = new ReportDataSource("BC06", lstData);
            localReport.DataSources.Add(reportDataSource);

            string[] streams;
            Warning[] warnings;
            const string type = "pdf";
            string mimeType, encoding, fileNameExtension;

            //Render the report             
            var renderedBytes = localReport.Render(type, string.Empty, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo tình trạng chi tiết Contact
        /// </summary>
        public ActionResult BC10()
        {
            return View();
        }
        public ActionResult ShowBC10()
        {
            // Param
            var lstData = new List<BC06Model>();
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC10.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", "(Từ ngày: " + DateTime.Now.ToString("dd/MM/yyyy") + " - Đến ngày: " + DateTime.Now.AddDays(10).ToString("dd/MM/yyyy") + ")"));

            var reportDataSource = new ReportDataSource("BC06", lstData);
            localReport.DataSources.Add(reportDataSource);

            string[] streams;
            Warning[] warnings;
            const string type = "pdf";
            string mimeType, encoding, fileNameExtension;
            
            //Render the report             
            const string deviceInfo = "<DeviceInfo>" +
                                       "  <OutputFormat>PDF</OutputFormat>" +
                                       "  <PageWidth>20in</PageWidth>" +
                                       "  <PageHeight>8.5in</PageHeight>" +
                                       "  <MarginTop>0.5in</MarginTop>" +
                                       "  <MarginLeft>0.2in</MarginLeft>" +
                                       "  <MarginRight>0.2in</MarginRight>" +
                                       "  <MarginBottom>1in</MarginBottom>" +
                                       "</DeviceInfo>";
            var renderedBytes = localReport.Render(type, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);
            return File(renderedBytes, mimeType);
        }

        /// <summary>
        /// Báo cáo năng suất cuộc gọi của CTV
        /// </summary>
        public ActionResult BC11()
        {
            return View();
        }
        public ActionResult ShowBC11()
        {
            var dict = new Dictionary<int, List<string>>();
            foreach (var item in dict.First().Value.Cast<List<string>>())
            {}

            // Param
            var lstData = new List<BC06Model>();
            var localReport = new LocalReport { ReportPath = Server.MapPath("~/Areas/Admin/Reports/rptBC11.rdlc") };
            localReport.SetParameters(new ReportParameter("Infomation", "(Từ ngày: " + DateTime.Now.ToString("dd/MM/yyyy") + " - Đến ngày: " + DateTime.Now.AddDays(10).ToString("dd/MM/yyyy") + ")"));

            var reportDataSource = new ReportDataSource("BC06", lstData);
            localReport.DataSources.Add(reportDataSource);

            string[] streams;
            Warning[] warnings;
            const string type = "pdf";
            string mimeType, encoding, fileNameExtension;

            //Render the report             
            var renderedBytes = localReport.Render(type, string.Empty, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);
            return File(renderedBytes, mimeType);
        }
    }
}
